﻿/**
 *
 * @file MapWrapper.h
 * @author Song
 * @date 2011-09-23
 */

#pragma once

#include <boost/uuid/uuid.hpp>
#include <boost/random.hpp>
#include <boost/thread.hpp>
#include <map>

namespace helpers {

	template <typename _Key, typename _Value>
	class MapWraper
	{
		typedef enum {
			  Zero = 0
			, Min = 0x0001
			, Max = 0xFFFF
		} KeyState;


	public:
		typedef _Key		Key;
		typedef _Value		Value;
		typedef std::map<Key, Value> ValueMap;
		typedef typename ValueMap::iterator iterator;
		
	public:
		MapWraper()
			: _keyDist(Min, Max)
			, _keyGenerator(_keyGen, _keyDist)
		{

		}

		~MapWraper() 
		{

		}

	public:
		iterator begin()
		{
			return _values.begin();
		}

		iterator end()
		{
			return _values.end();
		}

	// 提供加锁机制
	public:
		typedef boost::mutex::scoped_lock ScopedLock; 

		boost::mutex _mutex;

		/// 慎用.
		/// lock之后就不能继续调用 safe_add, safe_del, safe_find 函数了
		void lock()
		{
			_mutex.lock();
		}

		void unlock()
		{
			_mutex.unlock();
		}

	// 线程安全版本
	public:
		Key safe_add(const Value& v)
		{
			boost::mutex::scoped_lock lock(_mutex);
			return add(v);
		}
		
		/// 通过指定Key查找值
		Value safe_find(const Key& key) 
		{
			boost::mutex::scoped_lock lock(_mutex);
			return find(key);
		}

		/// 删除key对应的值
		void safe_del(const Key& key)
		{
			boost::mutex::scoped_lock lock(_mutex);
			del(key);
		}

		Value safe_find(const Key& key) const
		{
			safe_find(key);
		}
		
		Value& safe_at(const Key& key) 
		{
			boost::mutex::scoped_lock lock(_mutex);
			return at(key);
		}

	public:
		/// 添加一个值，返回值对应的Key
		Key add(const Value& v)
		{
			int32_t k = genKey();
			while (_values.count(k))
				k = genKey();

			_values.insert(std::make_pair(k, v));
			return k;
		}

		void del(const Key& key)
		{
			if (key >= Min && key <= Max) {
				if (_values.count(key)) {
					_values.erase(key);
				}
			}
		}

		Value find(const Key& key)
		{
			if (key >= Min && key <= Max) {
				iterator iter = _values.find(key);
				if (iter != _values.end()) {
					return (*iter).second;
				}
			}
			return Value();
		}
		
		Value& at(const Key& key)
		{
			if (key >= Min && key <= Max) {
				iterator iter = _values.find(key);
				if (iter != _values.end()) {
					return (*iter).second;
				}
			}
			throw std::exception("is not a valid key");
		}
	
	private:
		ValueMap _values;

	private:		
		int32_t genKey() 
		{
			return _keyGenerator();	
		}

		boost::mt19937 _keyGen; /**< 随机数生成器 */
		boost::uniform_int<> _keyDist; /**< 随机数分布 */
		boost::variate_generator< boost::mt19937&, boost::uniform_int<> > _keyGenerator; /**< 句柄索引生成器 */
	};


	template <typename key, typename _Value>
	class RandomKeyMap : public std::map<key, _Value>
	{
	private:
		RandomKeyMap()
		{		
			
		}
	};
	
	/// 可以自己生成整数型Key
	template <typename _Value>
	class RandomKeyMap<int, _Value> : public std::map<int, _Value>
	{
	public:
		typedef std::map<int, _Value>		Base;
		typedef typename Base::key_type		key_type;
		typedef typename Base::mapped_type	mapped_type;
		typedef typename Base::iterator		iterator;
	public:
		enum {
			  Zero = 0
			, Min = 0x0001
			, Max = 0xFFFF
		};

	public:
		RandomKeyMap()
			: _keyDist(Min, Max)
			, _keyGenerator(_keyGen, _keyDist)
		{

		}

	public:
		key_type add(const mapped_type& v)
		{
			int32_t k = genKey();
			while (this->count(k))
				k = genKey();

			this->insert(std::make_pair(k, v));
			return k;
		}

		void del(const key_type& key)
		{
			if (key >= Min && key <= Max) {
				if (this->count(key)) {
					this->erase(key);
				}
			}
		}

		mapped_type& at(const key_type& key)
		{
			if (key >= Min && key <= Max) {
				iterator iter = this->find(key);
				if (iter != this->end()) {
					return (*iter).second;
				}
			}
			throw std::exception("invalid key");
		}

	private:
		int32_t genKey() 
		{
			return _keyGenerator();	
		}

		boost::mt19937 _keyGen; /**< 随机数生成器 */
		boost::uniform_int<> _keyDist; /**< 随机数分布 */
		boost::variate_generator< boost::mt19937&, boost::uniform_int<> > _keyGenerator; /**< 句柄索引生成器 */
	};

	template <typename _Value>
	class SafeRandomKeyMap : public RandomKeyMap<int, _Value>
	{
	public:
		boost::recursive_mutex mutex;
		typedef boost::recursive_mutex::scoped_lock ScopedLock;
		
	public:
//		key_type safe_add(const mapped_type& v)
//		{
//			ScopedLock lock(mutex);
//			add(v);
//		}
	};
}
